#!/usr/bin/env python 
# -*- coding: utf-8 -*-
# @Time    : 2023/12/15 16:37
# @Author  : WJQ
# @Site    : 
# @File    : get_app_json.py
# @Software: PyCharm
import logging
import re, json, os, tarfile

CrawlerLogger = logging.getLogger('crawlerLogger')

def convert_4_bytes(n):
    bits=4*8
    return (n+2**(bits-1))%2**bits-2**(bits-1)

def hashCode(s):
    h=0
    n=len(s)
    for i,c in enumerate(s):
        h=h+ord(c)*31**(n-1-i)
    return convert_4_bytes(h)

def copy_Pkg_Down_wx(user_hash, appid, output_dir, device_id):
    hash_values = [
        hashCode(appid),
        hashCode(appid + "$__APP__"),
        hashCode(appid + "$__WITHOUT_MULTI_PLUGINCODE__"),
        hashCode(appid + "$__APP__$__WITHOUT_MULTI_PLUGINCODE__"),
        hashCode(appid + "$__PLUGINCODE__"),
        hashCode(appid + "$__WITHOUT_PLUGINCODE__"),
        hashCode(appid + "$__APP__$__WITHOUT_PLUGINCODE__")
    ]

    # 构建 adb 命令以列出所有 wxapkg 文件
    # list_cmd = 'adb -s {} shell "su -c ls /data/data/com.tencent.mm/MicroMsg/{}/appbrand/pkg/"'.format(device_id,
    #                                                                                                    user_hash)
    list_cmd = 'frida -l /Users/wht/yan/frida/shell.js -U installd -e "shell(\'ls /data/data/com.tencent.mm/MicroMsg/{}/appbrand/pkg/\')" -q'.format(user_hash)
    
    files = os.popen(list_cmd).read()

    for hash_value in hash_values :
        pattern = re.compile(r"_{}_\d+\.wxapkg".format(hash_value))
        for file_name in pattern.findall(files) :
            # 复制文件到 SD 卡
            # cp_cmd = 'adb -s {} shell "su -c cp /data/data/com.tencent.mm/MicroMsg/{}/appbrand/pkg/{} /sdcard/pkg/"'.format(
            #     device_id, user_hash, file_name)
            cp_cmd = 'frida -l /Users/wht/yan/frida/shell.js -U installd -e "shell(\'cp /data/data/com.tencent.mm/MicroMsg/{}/appbrand/pkg/{} /sdcard/pkg/\')" -q'.format(
                user_hash, file_name)
            os.system(cp_cmd)

            # 从 SD 卡拉取文件到本地
            down_cmd = 'adb -s {} pull /sdcard/pkg/{} {}'.format(device_id, file_name,
                                                                 os.path.join(output_dir, file_name))
            os.system(down_cmd)
            CrawlerLogger.info(f"[*] Copying {file_name} to local for device {device_id}")

def unpack_and_copy_json_wx(applets_name, pkg_dir, unpacker_path, json_output_dir):
    # 在目标文件夹下执行解压命令
    for pkg_file in os.listdir(pkg_dir):
        if pkg_file.endswith('.wxapkg'):
            full_path = os.path.join(pkg_dir, pkg_file)
            os.system(f"node {unpacker_path} {full_path}")

            # 解压后的文件夹通常与wxapkg文件名相同，但没有后缀
            unpacked_dir = os.path.splitext(full_path)[0]

            # 检查解压文件夹是否存在
            if os.path.exists(unpacked_dir):
                # 尝试复制 app.json 或 app-config.json
                json_file_path = os.path.join(unpacked_dir, 'app.json')
                if not os.path.exists(json_file_path):
                    json_file_path = os.path.join(unpacked_dir, 'app-config.json')

                if os.path.exists(json_file_path) :
                    # 读取原始 JSON 数据
                    with open(json_file_path, 'r', encoding='utf-8') as file :
                        json_data = json.load(file)

                    # 写入新文件
                    new_file_path = os.path.join(json_output_dir, applets_name + '.json')
                    with open(new_file_path, 'w', encoding='utf-8') as f :
                        json.dump(json_data, f, indent=4, ensure_ascii=False)
                    CrawlerLogger.info(f"[*] Copied and formatted JSON to {new_file_path}")

def copy_Pkg_Down_zfb(file_name, output_dir, device_id):

    # 复制文件到 SD 卡
    cp_cmd = 'adb -s {} shell "su -c cp /data/data/com.eg.android.AlipayGphone/files/nebulaInstallApps/{} /sdcard/pkg_zfb -r"'.format(
        device_id, file_name)
    os.system(cp_cmd)

    # 从 SD 卡拉取文件到本地
    down_cmd = 'adb -s {} pull /sdcard/pkg_zfb/{} {}'.format(device_id, file_name,
                                                         os.path.join(output_dir, file_name))
    os.system(down_cmd)
    CrawlerLogger.info(f"[*] Copying {file_name} to local for device {device_id}")

def unpack_and_copy_json_zfb(applets_name, pkg_dir, json_output_dir):
    # 遍历 pkg_dir 下的所有子目录
    for subdir in os.listdir(pkg_dir):
        subdir_path = os.path.join(pkg_dir, subdir)
        if os.path.isdir(subdir_path):
            # 在每个子目录中寻找 .tar 文件
            for pkg_file in os.listdir(subdir_path):
                if pkg_file.endswith('.tar'):
                    full_path = os.path.join(subdir_path, pkg_file)
                    # 解压 .tar 文件
                    with tarfile.open(full_path, 'r') as tar:
                        tar.extractall(subdir_path)

                    # 直接在 subdir_path 中查找 appConfig.json
                    json_file_path = os.path.join(subdir_path, 'appConfig.json')

                    if os.path.exists(json_file_path):
                            # 读取原始 JSON 数据
                            with open(json_file_path, 'r', encoding='utf-8') as file:
                                json_data = json.load(file)

                            # 写入新文件
                            new_file_path = os.path.join(json_output_dir, applets_name + '.json')
                            with open(new_file_path, 'w', encoding='utf-8') as f:
                                json.dump(json_data, f, indent=4, ensure_ascii=False)
                            CrawlerLogger.info(f"[*] Copied and formatted JSON to {new_file_path}")


def copy_Pkg_Down_bd(file_name, output_dir, device_id):

    # 复制文件到 SD 卡
    cp_cmd = 'adb -s {} shell "su -c cp /data/data/com.baidu.swan/files/aiapps_folder/{} /sdcard/pkg_bd -r"'.format(
        device_id, file_name)
    os.system(cp_cmd)

    # 从 SD 卡拉取文件到本地
    down_cmd = 'adb -s {} pull /sdcard/pkg_bd/{} {}'.format(device_id, file_name,
                                                         os.path.join(output_dir, file_name))
    os.system(down_cmd)
    CrawlerLogger.info(f"[*] Copying {file_name} to local for device {device_id}")

def unpack_and_copy_json_bd(applets_name, pkg_dir, json_output_dir):
    for subdir in os.listdir(pkg_dir) :
        subdir_path = os.path.join(pkg_dir, subdir)
        # 直接在 subdir_path 中查找 appConfig.json
        json_file_path = os.path.join(subdir_path, 'app.json')

        if os.path.exists(json_file_path) :
            # 读取原始 JSON 数据
            with open(json_file_path, 'r', encoding='utf-8') as file :
                json_data = json.load(file)

            # 写入新文件
            new_file_path = os.path.join(json_output_dir, applets_name + '.json')
            with open(new_file_path, 'w', encoding='utf-8') as f :
                json.dump(json_data, f, indent=4, ensure_ascii=False)
            CrawlerLogger.info(f"[*] Copied and formatted JSON to {new_file_path}")